module.exports = options => {
  const methodDict = {
    1: 'GET',
    2: 'POST',
    3: 'PUT',
    4: 'DELETE',
    5: 'OTHER',
    'GET': 1,
    'POST': 2,
    'PUT': 3,
    'DELETE': 4,
  }
  return async (ctx, next) => {
    const now = Date.now()
    ctx.user = {}
    // 管理终端
    const token = ctx.headers.token ? ctx.header.token.split('__') : ''
    // 第三方应用
    const appToken = ctx.headers.authentication
      ? Buffer.from(ctx.headers.authentication).toString().replace('Basic ')
      : ''
    let spm = 3
    // 优先 token 存在且在有效期
    if (token) {
      spm = 2
      if (token && token[2] > now) {
        ctx.user = await ctx.model.User.findOne({ session: ctx.headers.token }, '-password') || {}
        console.log('load', ctx.user.name, ctx.user._id)
      }
    } else if (appToken) {
      spm = 1
      const now = Date.now()
      const info = appToken.split(':')
      const accessKey = info[0]
      const accessToken = info[1]
      const app = await ctx.model.Application.findOne({ accessKey, accessToken, expiredAt: { $lte: now } })
                           .populate('user', '-password')
      // 存在且未过期
      if (app) {
        ctx.user = app.user
      }
    }
    const { path, method } = ctx
    await next()
    if (!path.startsWith('/api/v1/log')) {
      await ctx.model.Log.create({
        path,
        method: methodDict[method] || 5,
        user: ctx.user._id,
        username: ctx.user.name,
        spm,
        state: ctx.status,
      })
    }
  }
}
